using System;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using OracleInternal.Common;
using OracleInternal.Secure.Network;

namespace OracleInternal.Network
{
	internal class SEPS
	{
		[StructLayout(LayoutKind.Sequential)]
		private class CRYPT_SEQUENCE_OF_ANY
		{
			public uint cValue;

			public IntPtr rgValue;
		}

		[StructLayout(LayoutKind.Sequential)]
		private class CRYPTOAPI_BLOB
		{
			public uint cbData;

			public IntPtr pData;
		}

		[StructLayout(LayoutKind.Sequential)]
		private class CRYPT_CONTENT_INFO
		{
			public IntPtr pszObjId;

			public CRYPTOAPI_BLOB Content;
		}

		[StructLayout(LayoutKind.Sequential)]
		private class CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY
		{
			public IntPtr pszObjId;

			public uint cValue;

			public IntPtr rgValue;
		}

		internal enum PbeAlgorithmType
		{
			pbeSHA_3DES_CBC,
			pbeSHA_RC2_40_CBC
		}

		private const uint X509_ASN_ENCODING = 1u;

		private const uint PKCS_7_ASN_ENCODING = 65536u;

		private const uint X509_SEQUENCE_OF_ANY = 34u;

		private const uint PKCS_CONTENT_INFO = 33u;

		private const uint PKCS_CONTENT_INFO_SEQUENCE_OF_ANY = 23u;

		private const uint X509_OCTET_STRING = 25u;

		private const uint X509_OBJECT_IDENTIFIER = 73u;

		private const uint ENCODING = 65537u;

		private const uint HASH_BLOCK_SIZE = 64u;

		private const string pkcs_12_secretBag = "1.2.840.113549.1.12.10.1.5";

		private const string oracleOID = "1.2.840.113549.1.16.12.12";

		private const string pbeWithSHAAnd3_KeyTripleDES_CBC = "1.2.840.113549.1.12.1.3";

		private const string pbeWithSHAAnd40BitRC2_CBC = "1.2.840.113549.1.12.1.6";

		private const string szOID_PKCS_7_DATA = "1.2.840.113549.1.7.1";

		private const string szOID_PKCS_7_ENCRYPTED = "1.2.840.113549.1.7.6";

		private const string WALLETFILENAME = "cwallet.sso";

		[DllImport("crypt32.dll", SetLastError = true)]
		private static extern bool CryptDecodeObject(uint dwCertEncodingType, string lpszStructType, IntPtr pbEncoded, uint cbEncoded, uint dwFlags, IntPtr pvStructInfo, ref uint pcbStructInfo);

		[DllImport("crypt32.dll", SetLastError = true)]
		private static extern bool CryptDecodeObject(uint dwCertEncodingType, uint lpszStructType, IntPtr pbEncoded, uint cbEncoded, uint dwFlags, IntPtr pvStructInfo, ref uint pcbStructInfo);

		internal static void GetSEPSUandP(string ConnectString, out string Userid, out SecureString PW, out string WP, out string WF)
		{
			SqlNetOraConfig sqlNetOraConfig = new SqlNetOraConfig();
			Hashtable HT = null;
			string Dir = null;
			string WP2 = null;
			string text = "";
			byte[] array = null;
			bool bTraceLevelNetwork = ProviderConfig.m_bTraceLevelNetwork;
			PW = null;
			Userid = (WF = (WP = null));
			try
			{
				SqlNetOraConfig.GetWalletLoc(null, sqlNetOraConfig, out Dir, out HT);
				if (!string.IsNullOrEmpty(Dir))
				{
					text = "FILE";
				}
				else if (HT != null)
				{
					text = ((string)HT["METHOD"]).ToUpperInvariant();
					if (text != null && text == "FILE")
					{
						Dir = (string)HT["DIRECTORY"];
					}
				}
				if (bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "Wallet Location = " + Dir);
				}
				if (string.IsNullOrEmpty(Dir))
				{
					throw new NetworkException(-6400);
				}
				Dir = ConfigBaseClass.GetResolvedFileLocation(Dir);
				Dir = SqlNetOraConfig.HandlePathSeparators(Dir);
				if (sqlNetOraConfig != null)
				{
					WP2 = sqlNetOraConfig["WALLET_PASSWORD"];
				}
				array = WalletReader.ReadWallet(Dir, ref WP2);
			}
			catch (NetworkException ex)
			{
				if (bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS: Wallet config invalid.");
				}
				throw ex;
			}
			catch (Exception inner)
			{
				if (bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS: Open wallet failed.");
				}
				throw new NetworkException(-6400, inner);
			}
			WP = Dir;
			WF = "cwallet.sso";
			if (!ExtractDataAndKeyParametersFromPFX(array, (uint)array.Length, out var EncryptedData, out var Salt, out var dwIterationCount, out var AlgType))
			{
				return;
			}
			byte[] encodedBags;
			try
			{
				ICryptoTransform transform = GeneratePbeSHA1Decryptor(WP2, Salt, dwIterationCount, AlgType);
				MemoryStream memoryStream = new MemoryStream();
				CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
				cryptoStream.Write(EncryptedData, 0, EncryptedData.Length);
				encodedBags = memoryStream.ToArray();
				cryptoStream.Close();
			}
			catch (Exception ex2)
			{
				if (bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Error, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS: SHA1Decryptor failure: " + ex2);
				}
				throw new NetworkException(12578, ex2);
			}
			SortedList listOfSecretBags = GetListOfSecretBags(encodedBags);
			if (listOfSecretBags.Count > 0)
			{
				string text2 = null;
				string text3 = null;
				for (int i = 0; i < listOfSecretBags.Count; i++)
				{
					text3 = (string)listOfSecretBags.GetKey(i);
					if (text3.StartsWith("oracle.security.client.connect_string"))
					{
						if (object.Equals((string)listOfSecretBags.GetByIndex(i), ConnectString) && i + 2 < listOfSecretBags.Count)
						{
							text2 = text3.Substring(37, text3.Length - 37);
						}
					}
					else if (text2 != null && string.Equals("oracle.security.client.username" + text2, text3))
					{
						Userid = (string)listOfSecretBags.GetByIndex(i);
					}
					else if (text2 != null && string.Equals("oracle.security.client.password" + text2, text3))
					{
						PW = (SecureString)listOfSecretBags.GetByIndex(i);
					}
				}
			}
			if (bTraceLevelNetwork)
			{
				if (listOfSecretBags.Count == 0)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS: No entries found");
				}
				if (string.IsNullOrEmpty(Userid))
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS userid is null.");
				}
				if (PW == null)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Sqlnet, OracleTraceClassName.SEPS, OracleTraceFuncName.GetSEPSUandP, "SEPS password is null.");
				}
			}
		}

		private static SortedList GetListOfSecretBags(byte[] EncodedBags)
		{
			SortedList sortedList = new SortedList();
			bool flag = false;
			IntPtr pvStructInfo = IntPtr.Zero;
			IntPtr pvStructInfo2 = IntPtr.Zero;
			IntPtr pvStructInfo3 = IntPtr.Zero;
			_ = IntPtr.Zero;
			IntPtr pvStructInfo4 = IntPtr.Zero;
			CRYPT_SEQUENCE_OF_ANY cRYPT_SEQUENCE_OF_ANY = new CRYPT_SEQUENCE_OF_ANY();
			new CRYPT_SEQUENCE_OF_ANY();
			CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY cRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = new CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY();
			CRYPTOAPI_BLOB cRYPTOAPI_BLOB = new CRYPTOAPI_BLOB();
			byte[] array = null;
			int num = 0;
			byte[] array2 = null;
			byte[] array3 = null;
			try
			{
				int num2 = 0;
				if (EncodedBags[1] == 130)
				{
					num2 = EncodedBags[2] * 256 + EncodedBags[3];
				}
				else if (EncodedBags[1] == 131)
				{
					byte[] value = new byte[4]
					{
						0,
						EncodedBags[2],
						EncodedBags[3],
						EncodedBags[4]
					};
					byte[] value2 = new byte[4]
					{
						EncodedBags[4],
						EncodedBags[3],
						EncodedBags[2],
						0
					};
					num2 = ((!BitConverter.IsLittleEndian) ? BitConverter.ToInt32(value, 0) : BitConverter.ToInt32(value2, 0));
				}
				if (num2 > 0)
				{
					if (EncodedBags.Length < num2 + 4)
					{
						int num3 = num2 + 4 - EncodedBags.Length;
						array = new byte[EncodedBags.Length + num3];
						EncodedBags.CopyTo(array, 0);
						flag = AllocAndDecode(34u, array, out pvStructInfo);
					}
					else
					{
						flag = AllocAndDecode(34u, EncodedBags, out pvStructInfo);
					}
				}
				if (!flag)
				{
					throw new ApplicationException();
				}
				Marshal.PtrToStructure(pvStructInfo, cRYPT_SEQUENCE_OF_ANY);
				for (int i = 0; i < cRYPT_SEQUENCE_OF_ANY.cValue; i++)
				{
					Marshal.PtrToStructure((IntPtr)(cRYPT_SEQUENCE_OF_ANY.rgValue.ToInt64() + i * Marshal.SizeOf(cRYPTOAPI_BLOB)), cRYPTOAPI_BLOB);
					if (!AllocAndDecode(34u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo2))
					{
						throw new ApplicationException();
					}
					Marshal.PtrToStructure(pvStructInfo2, cRYPTOAPI_BLOB);
					Marshal.PtrToStructure(cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB);
					array2 = new byte[cRYPTOAPI_BLOB.cbData];
					Marshal.Copy(cRYPTOAPI_BLOB.pData, array2, 0, array2.Length);
					if (DecodeOID(array2) == "1.2.840.113549.1.12.10.1.5")
					{
						Marshal.PtrToStructure(pvStructInfo2, cRYPTOAPI_BLOB);
						Marshal.PtrToStructure((IntPtr)(cRYPTOAPI_BLOB.pData.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB)), cRYPTOAPI_BLOB);
						array3 = new byte[cRYPTOAPI_BLOB.cbData];
						Marshal.Copy(cRYPTOAPI_BLOB.pData, array3, 0, array3.Length);
						byte[] pbByteEncoded = ASNDecodeData(array3);
						if (!AllocAndDecode(33u, pbByteEncoded, out pvStructInfo4))
						{
							throw new ApplicationException();
						}
						Marshal.PtrToStructure(pvStructInfo4, cRYPT_CONTENT_INFO_SEQUENCE_OF_ANY);
						if (Marshal.PtrToStringAnsi(cRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.pszObjId) == "1.2.840.113549.1.16.12.12")
						{
							num++;
							if (!AllocAndDecode(34u, cRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.rgValue, cRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.cValue, out pvStructInfo3))
							{
								throw new ApplicationException();
							}
							Marshal.PtrToStructure(pvStructInfo3, cRYPTOAPI_BLOB);
							Marshal.PtrToStructure(cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB);
							array3 = new byte[cRYPTOAPI_BLOB.cbData];
							Marshal.Copy(cRYPTOAPI_BLOB.pData, array3, 0, array3.Length);
							string text = (string)ASNDecodeUTF8String(array3, bReturnSecureString: false);
							Marshal.PtrToStructure(pvStructInfo3, cRYPTOAPI_BLOB);
							Marshal.PtrToStructure((IntPtr)(cRYPTOAPI_BLOB.pData.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB)), cRYPTOAPI_BLOB);
							array3 = new byte[cRYPTOAPI_BLOB.cbData];
							Marshal.Copy(cRYPTOAPI_BLOB.pData, array3, 0, array3.Length);
							object obj = null;
							obj = ((!text.Contains("oracle.security.client.password")) ? ASNDecodeUTF8String(array3, bReturnSecureString: false) : ASNDecodeUTF8String(array3, bReturnSecureString: true));
							sortedList.Add(text, obj);
							if (pvStructInfo3 != IntPtr.Zero)
							{
								Marshal.FreeHGlobal(pvStructInfo3);
							}
							pvStructInfo3 = IntPtr.Zero;
						}
						if (pvStructInfo4 != IntPtr.Zero)
						{
							Marshal.FreeHGlobal(pvStructInfo4);
						}
						pvStructInfo4 = IntPtr.Zero;
					}
					if (pvStructInfo2 != IntPtr.Zero)
					{
						Marshal.FreeHGlobal(pvStructInfo2);
					}
					pvStructInfo2 = IntPtr.Zero;
				}
				if (pvStructInfo != IntPtr.Zero)
				{
					Marshal.FreeHGlobal(pvStructInfo);
					return sortedList;
				}
				return sortedList;
			}
			catch (Exception ex)
			{
				if (ProviderConfig.m_bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Error, OracleTraceClassName.SEPS, OracleTraceFuncName.GetListOfSecretBags, "SEPS: GetListOfSecretBags failure: " + ex);
					return sortedList;
				}
				return sortedList;
			}
		}

		private static bool ExtractDataAndKeyParametersFromPFX(byte[] pbPKCS12, uint dwPKCS12, out byte[] EncryptedData, out byte[] Salt, out int dwIterationCount, out PbeAlgorithmType AlgType)
		{
			bool flag = false;
			IntPtr pvStructInfo = IntPtr.Zero;
			IntPtr pvStructInfo2 = IntPtr.Zero;
			IntPtr pvStructInfo3 = IntPtr.Zero;
			IntPtr pvStructInfo4 = IntPtr.Zero;
			_ = IntPtr.Zero;
			IntPtr pvStructInfo5 = IntPtr.Zero;
			IntPtr zero = IntPtr.Zero;
			CRYPT_SEQUENCE_OF_ANY cRYPT_SEQUENCE_OF_ANY = new CRYPT_SEQUENCE_OF_ANY();
			CRYPT_SEQUENCE_OF_ANY cRYPT_SEQUENCE_OF_ANY2 = new CRYPT_SEQUENCE_OF_ANY();
			CRYPTOAPI_BLOB cRYPTOAPI_BLOB = new CRYPTOAPI_BLOB();
			CRYPT_CONTENT_INFO cRYPT_CONTENT_INFO = new CRYPT_CONTENT_INFO();
			new CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY();
			CRYPTOAPI_BLOB cRYPTOAPI_BLOB2 = new CRYPTOAPI_BLOB();
			EncryptedData = null;
			Salt = null;
			dwIterationCount = 0;
			AlgType = PbeAlgorithmType.pbeSHA_3DES_CBC;
			try
			{
				if (!AllocAndDecode(34u, pbPKCS12, out pvStructInfo))
				{
					throw new ApplicationException();
				}
				Marshal.PtrToStructure(pvStructInfo, cRYPT_SEQUENCE_OF_ANY);
				if (cRYPT_SEQUENCE_OF_ANY.cValue < 2)
				{
					throw new ApplicationException();
				}
				zero = (IntPtr)(cRYPT_SEQUENCE_OF_ANY.rgValue.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				if (!AllocAndDecode(33u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo4))
				{
					throw new ApplicationException();
				}
				Marshal.FreeHGlobal(pvStructInfo);
				pvStructInfo = IntPtr.Zero;
				Marshal.PtrToStructure(pvStructInfo4, cRYPT_CONTENT_INFO);
				if (Marshal.PtrToStringAnsi(cRYPT_CONTENT_INFO.pszObjId) != "1.2.840.113549.1.7.1")
				{
					throw new ApplicationException();
				}
				if (!AllocAndDecode(25u, cRYPT_CONTENT_INFO.Content.pData, cRYPT_CONTENT_INFO.Content.cbData, out pvStructInfo5))
				{
					throw new ApplicationException();
				}
				Marshal.FreeHGlobal(pvStructInfo4);
				pvStructInfo4 = IntPtr.Zero;
				Marshal.PtrToStructure(pvStructInfo5, cRYPTOAPI_BLOB2);
				if (!AllocAndDecode(34u, cRYPTOAPI_BLOB2.pData, cRYPTOAPI_BLOB2.cbData, out pvStructInfo))
				{
					throw new ApplicationException();
				}
				Marshal.FreeHGlobal(pvStructInfo5);
				pvStructInfo5 = IntPtr.Zero;
				Marshal.PtrToStructure(pvStructInfo, cRYPT_SEQUENCE_OF_ANY);
				zero = cRYPT_SEQUENCE_OF_ANY.rgValue;
				bool flag2 = false;
				for (int i = 0; i < cRYPT_SEQUENCE_OF_ANY.cValue; i++)
				{
					Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
					if (!AllocAndDecode(33u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo4))
					{
						throw new ApplicationException();
					}
					Marshal.FreeHGlobal(pvStructInfo);
					pvStructInfo = IntPtr.Zero;
					Marshal.PtrToStructure(pvStructInfo4, cRYPT_CONTENT_INFO);
					if (Marshal.PtrToStringAnsi(cRYPT_CONTENT_INFO.pszObjId) == "1.2.840.113549.1.7.6")
					{
						flag2 = true;
						break;
					}
					zero = (IntPtr)(zero.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				}
				if (!flag2)
				{
					throw new ApplicationException();
				}
				if (!AllocAndDecode(34u, cRYPT_CONTENT_INFO.Content.pData, cRYPT_CONTENT_INFO.Content.cbData, out pvStructInfo))
				{
					throw new ApplicationException();
				}
				Marshal.FreeHGlobal(pvStructInfo4);
				pvStructInfo4 = IntPtr.Zero;
				Marshal.PtrToStructure(pvStructInfo, cRYPT_SEQUENCE_OF_ANY);
				zero = (IntPtr)(cRYPT_SEQUENCE_OF_ANY.rgValue.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				if (!AllocAndDecode(34u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo2))
				{
					throw new ApplicationException();
				}
				Marshal.FreeHGlobal(pvStructInfo);
				pvStructInfo = IntPtr.Zero;
				Marshal.PtrToStructure(pvStructInfo2, cRYPT_SEQUENCE_OF_ANY);
				Marshal.PtrToStructure(cRYPT_SEQUENCE_OF_ANY.rgValue, cRYPTOAPI_BLOB);
				byte[] array = new byte[cRYPTOAPI_BLOB.cbData];
				Marshal.Copy(cRYPTOAPI_BLOB.pData, array, 0, array.Length);
				if (DecodeOID(array) != "1.2.840.113549.1.7.1")
				{
					throw new ApplicationException();
				}
				zero = (IntPtr)(cRYPT_SEQUENCE_OF_ANY.rgValue.ToInt64() + 2 * Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				byte[] array2 = new byte[cRYPTOAPI_BLOB.cbData];
				Marshal.Copy(cRYPTOAPI_BLOB.pData, array2, 0, array2.Length);
				EncryptedData = ASNDecodeData(array2);
				zero = (IntPtr)(cRYPT_SEQUENCE_OF_ANY.rgValue.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				if (!AllocAndDecode(34u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo))
				{
					throw new ApplicationException();
				}
				Marshal.PtrToStructure(pvStructInfo, cRYPTOAPI_BLOB);
				Marshal.PtrToStructure(cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB);
				array = new byte[cRYPTOAPI_BLOB.cbData];
				Marshal.Copy(cRYPTOAPI_BLOB.pData, array, 0, array.Length);
				string a = DecodeOID(array);
				if (a != "1.2.840.113549.1.12.1.3" && a != "1.2.840.113549.1.12.1.6")
				{
					throw new ApplicationException();
				}
				if (a == "1.2.840.113549.1.12.1.3")
				{
					AlgType = PbeAlgorithmType.pbeSHA_3DES_CBC;
				}
				else if (a == "1.2.840.113549.1.12.1.6")
				{
					AlgType = PbeAlgorithmType.pbeSHA_RC2_40_CBC;
				}
				Marshal.PtrToStructure(pvStructInfo, cRYPTOAPI_BLOB);
				zero = (IntPtr)(cRYPTOAPI_BLOB.pData.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				if (!AllocAndDecode(34u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo3))
				{
					throw new ApplicationException();
				}
				Marshal.PtrToStructure(pvStructInfo3, cRYPT_SEQUENCE_OF_ANY2);
				Marshal.PtrToStructure(cRYPT_SEQUENCE_OF_ANY2.rgValue, cRYPTOAPI_BLOB);
				if (!AllocAndDecode(25u, cRYPTOAPI_BLOB.pData, cRYPTOAPI_BLOB.cbData, out pvStructInfo5))
				{
					throw new ApplicationException();
				}
				Marshal.PtrToStructure(pvStructInfo5, cRYPTOAPI_BLOB);
				Salt = new byte[cRYPTOAPI_BLOB.cbData];
				Marshal.Copy(cRYPTOAPI_BLOB.pData, Salt, 0, Salt.Length);
				Marshal.PtrToStructure(pvStructInfo3, cRYPT_SEQUENCE_OF_ANY2);
				zero = (IntPtr)(cRYPT_SEQUENCE_OF_ANY2.rgValue.ToInt64() + Marshal.SizeOf(cRYPTOAPI_BLOB));
				Marshal.PtrToStructure(zero, cRYPTOAPI_BLOB);
				array2 = new byte[cRYPTOAPI_BLOB.cbData];
				Marshal.Copy(cRYPTOAPI_BLOB.pData, array2, 0, array2.Length);
				byte[] pbData = ASNDecodeInteger(array2);
				dwIterationCount = CalculateInteger(pbData);
				return true;
			}
			catch (Exception ex)
			{
				if (ProviderConfig.m_bTraceLevelNetwork)
				{
					Trace.Write(OracleTraceLevel.Network, OracleTraceTag.Error, OracleTraceClassName.SEPS, OracleTraceFuncName.ExtractDataAndKeyParametersFromPFX, "SEPS: ExtractDataAndKeyParametersFromPFX failure." + ex);
				}
				throw new NetworkException(12578, ex);
			}
		}

		public static void FillBuffer(byte[] From, byte[] To)
		{
			int i;
			for (i = 0; i + From.Length < To.Length; i += From.Length)
			{
				From.CopyTo(To, i);
			}
			Array.Copy(From, 0, To, i, To.Length - i);
		}

		public static ICryptoTransform GeneratePbeSHA1Decryptor(string password, byte[] salt, int sha1iterations, PbeAlgorithmType AlgType)
		{
			byte[] array = new byte[64];
			byte[] array2 = new byte[64];
			byte[] array3 = new byte[64];
			int num = 24;
			switch (AlgType)
			{
			case PbeAlgorithmType.pbeSHA_3DES_CBC:
				num = 24;
				break;
			case PbeAlgorithmType.pbeSHA_RC2_40_CBC:
				num = 5;
				break;
			}
			byte[] array4 = new byte[num];
			byte[] array5 = new byte[8];
			for (uint num2 = 0u; num2 < array.Length; num2++)
			{
				array[num2] = 1;
			}
			for (uint num2 = 0u; num2 < array2.Length; num2++)
			{
				array2[num2] = 2;
			}
			byte[] array6 = new byte[Encoding.Unicode.GetBytes(password).Length + 2];
			Encoding.Unicode.GetBytes(password).CopyTo(array6, 0);
			for (int i = 0; i < array6.Length; i += 2)
			{
				byte b = array6[i];
				array6[i] = array6[i + 1];
				array6[i + 1] = b;
			}
			uint num3 = (uint)(((long)array6.Length + 64L - 1) / 64 * 64);
			uint num4 = (uint)(((long)salt.Length + 64L - 1) / 64 * 64);
			byte[] array7 = new byte[num3];
			byte[] array8 = new byte[num4];
			FillBuffer(array6, array7);
			FillBuffer(salt, array8);
			SHA1CryptoServiceProvider sHA1CryptoServiceProvider = new SHA1CryptoServiceProvider();
			byte[] array9 = new byte[64 + num3 + num4];
			array.CopyTo(array9, 0);
			array8.CopyTo(array9, array.Length);
			array7.CopyTo(array9, array.Length + array8.Length);
			byte[] array10 = sHA1CryptoServiceProvider.ComputeHash(array9);
			sHA1CryptoServiceProvider.Dispose();
			for (int j = 0; j < sha1iterations - 1; j++)
			{
				SHA1CryptoServiceProvider sHA1CryptoServiceProvider2 = new SHA1CryptoServiceProvider();
				array10 = sHA1CryptoServiceProvider2.ComputeHash(array10);
				sHA1CryptoServiceProvider2.Dispose();
			}
			switch (AlgType)
			{
			case PbeAlgorithmType.pbeSHA_RC2_40_CBC:
				Array.Copy(array10, 0, array4, 0, 5);
				break;
			case PbeAlgorithmType.pbeSHA_3DES_CBC:
			{
				Array.Copy(array10, 0, array4, 0, 20);
				FillBuffer(array10, array3);
				ushort num5 = 1;
				ushort num6 = 1;
				uint num2 = 64u;
				do
				{
					num2--;
					num5 = (ushort)(num5 + array7[num2]);
					num5 = (ushort)(num5 + array3[num2]);
					array7[num2] = (byte)num5;
					num5 = (ushort)(num5 >> 8);
					num6 = (ushort)(num6 + array8[num2]);
					num6 = (ushort)(num6 + array3[num2]);
					array8[num2] = (byte)num6;
					num6 = (ushort)(num6 >> 8);
				}
				while (num2 != 0);
				SHA1CryptoServiceProvider sHA1CryptoServiceProvider3 = new SHA1CryptoServiceProvider();
				array9 = new byte[64 + num3 + num4];
				array.CopyTo(array9, 0);
				array8.CopyTo(array9, array.Length);
				array7.CopyTo(array9, array.Length + array8.Length);
				array10 = sHA1CryptoServiceProvider3.ComputeHash(array9);
				sHA1CryptoServiceProvider3.Dispose();
				for (int k = 0; k < sha1iterations - 1; k++)
				{
					SHA1CryptoServiceProvider sHA1CryptoServiceProvider4 = new SHA1CryptoServiceProvider();
					array10 = sHA1CryptoServiceProvider4.ComputeHash(array10);
					sHA1CryptoServiceProvider4.Dispose();
				}
				Array.Copy(array10, 0, array4, 20, 4);
				break;
			}
			}
			SHA1CryptoServiceProvider sHA1CryptoServiceProvider5 = new SHA1CryptoServiceProvider();
			FillBuffer(array6, array7);
			FillBuffer(salt, array8);
			array9 = new byte[64 + num3 + num4];
			array2.CopyTo(array9, 0);
			array8.CopyTo(array9, array.Length);
			array7.CopyTo(array9, array.Length + array8.Length);
			array10 = sHA1CryptoServiceProvider5.ComputeHash(array9);
			sHA1CryptoServiceProvider5.Dispose();
			for (int l = 0; l < sha1iterations - 1; l++)
			{
				SHA1CryptoServiceProvider sHA1CryptoServiceProvider6 = new SHA1CryptoServiceProvider();
				array10 = sHA1CryptoServiceProvider6.ComputeHash(array10);
				sHA1CryptoServiceProvider6.Dispose();
			}
			Array.Copy(array10, 0, array5, 0, 8);
			return AlgType switch
			{
				PbeAlgorithmType.pbeSHA_3DES_CBC => new TripleDESCryptoServiceProvider().CreateDecryptor(array4, array5), 
				PbeAlgorithmType.pbeSHA_RC2_40_CBC => new RC2CryptoServiceProvider().CreateDecryptor(array4, array5), 
				_ => null, 
			};
		}

		private static bool AllocAndDecode(uint lpszStructType, byte[] pbByteEncoded, out IntPtr pvStructInfo)
		{
			bool flag = false;
			uint pcbStructInfo = 0u;
			pvStructInfo = IntPtr.Zero;
			IntPtr intPtr = Marshal.AllocHGlobal(pbByteEncoded.Length);
			uint num = (uint)pbByteEncoded.Length;
			Marshal.Copy(pbByteEncoded, 0, intPtr, (int)num);
			flag = CryptDecodeObject(65537u, lpszStructType, intPtr, num, 0u, pvStructInfo, ref pcbStructInfo);
			if (flag)
			{
				pvStructInfo = Marshal.AllocHGlobal((int)pcbStructInfo);
				if (pvStructInfo != IntPtr.Zero)
				{
					flag = CryptDecodeObject(65537u, lpszStructType, intPtr, num, 0u, pvStructInfo, ref pcbStructInfo);
				}
			}
			Marshal.GetLastWin32Error();
			return flag;
		}

		private static bool AllocAndDecode(string lpszStructType, byte[] pbByteEncoded, out IntPtr pvStructInfo)
		{
			bool flag = false;
			uint pcbStructInfo = 0u;
			pvStructInfo = IntPtr.Zero;
			IntPtr intPtr = Marshal.AllocHGlobal(pbByteEncoded.Length);
			uint num = (uint)pbByteEncoded.Length;
			Marshal.Copy(pbByteEncoded, 0, intPtr, (int)num);
			flag = CryptDecodeObject(65537u, lpszStructType, intPtr, num, 0u, pvStructInfo, ref pcbStructInfo);
			if (flag)
			{
				pvStructInfo = Marshal.AllocHGlobal((int)pcbStructInfo);
				if (pvStructInfo != IntPtr.Zero)
				{
					flag = CryptDecodeObject(65537u, lpszStructType, intPtr, num, 0u, pvStructInfo, ref pcbStructInfo);
				}
			}
			return flag;
		}

		private static bool AllocAndDecode(uint lpszStructType, IntPtr pbEncoded, uint cbEncoded, out IntPtr pvStructInfo)
		{
			bool flag = false;
			uint pcbStructInfo = 0u;
			pvStructInfo = IntPtr.Zero;
			flag = CryptDecodeObject(65537u, lpszStructType, pbEncoded, cbEncoded, 0u, pvStructInfo, ref pcbStructInfo);
			if (flag)
			{
				pvStructInfo = Marshal.AllocHGlobal((int)pcbStructInfo);
				if (pvStructInfo != IntPtr.Zero)
				{
					flag = CryptDecodeObject(65537u, lpszStructType, pbEncoded, cbEncoded, 0u, pvStructInfo, ref pcbStructInfo);
				}
			}
			return flag;
		}

		private static bool AllocAndDecode(string lpszStructType, IntPtr pbEncoded, uint cbEncoded, out IntPtr pvStructInfo)
		{
			bool flag = false;
			uint pcbStructInfo = 0u;
			pvStructInfo = IntPtr.Zero;
			flag = CryptDecodeObject(65537u, lpszStructType, pbEncoded, cbEncoded, 0u, pvStructInfo, ref pcbStructInfo);
			if (flag)
			{
				pvStructInfo = Marshal.AllocHGlobal((int)pcbStructInfo);
				if (pvStructInfo != IntPtr.Zero)
				{
					flag = CryptDecodeObject(65537u, lpszStructType, pbEncoded, cbEncoded, 0u, pvStructInfo, ref pcbStructInfo);
				}
			}
			return flag;
		}

		public static string DecodeOID(byte[] pbEncodedOID)
		{
			int num = 2;
			int[] array = null;
			string str = "";
			int i;
			for (i = 3; i < pbEncodedOID.Length; i++)
			{
				if ((pbEncodedOID[i] & 0x80) == 0)
				{
					num++;
				}
			}
			array = new int[num];
			array[0] = Convert.ToInt32(pbEncodedOID[2]) / 40;
			array[1] = Convert.ToInt32(pbEncodedOID[2]) % 40;
			int num2 = 0;
			i = 2;
			int num3 = 3;
			for (; i < array.Length; i++)
			{
				bool flag = true;
				num2 = 0;
				do
				{
					int num4 = Convert.ToInt32(pbEncodedOID[num3++]);
					if ((num4 & 0x80) == 128)
					{
						num2 = (num2 + (num4 & 0x7F)) * 128;
						continue;
					}
					num2 += num4;
					flag = false;
				}
				while (flag);
				array[i] = num2;
			}
			for (i = 0; i < array.Length - 1; i++)
			{
				str = str + Convert.ToString(array[i], 10) + ".";
			}
			return str + Convert.ToString(array[^1], 10);
		}

		public static byte[] ASNDecodeData(byte[] pbData)
		{
			byte[] array = null;
			uint num = 0u;
			if (pbData[0] != 128 && pbData[0] != 160)
			{
				return null;
			}
			int i;
			if ((pbData[1] & 0x80) > 0)
			{
				uint num2 = pbData[1] & 0x7Fu;
				if (num2 > 4)
				{
					return null;
				}
				for (i = 0; i < num2; i++)
				{
					num |= (uint)(pbData[i + 2] << ((int)(num2 - 1) - i) * 8);
				}
			}
			else
			{
				num = pbData[1];
				i = 0;
			}
			if (pbData[i + 2] == 0)
			{
				num--;
				array = new byte[num];
				Array.Copy(pbData, i + 3, array, 0, (int)num);
			}
			else
			{
				array = new byte[num];
				Array.Copy(pbData, i + 2, array, 0, (int)num);
			}
			return array;
		}

		public static object ASNDecodeUTF8String(byte[] pbData, bool bReturnSecureString)
		{
			byte[] array = null;
			uint num = 0u;
			if (pbData[0] != 12)
			{
				return null;
			}
			int i;
			if ((pbData[1] & 0x80) > 0)
			{
				uint num2 = pbData[1] & 0x7Fu;
				if (num2 > 4)
				{
					return null;
				}
				for (i = 0; i < num2; i++)
				{
					num |= (uint)(pbData[i + 2] << ((int)(num2 - 1) - i) * 8);
				}
			}
			else
			{
				num = pbData[1];
				i = 0;
			}
			if (pbData[i + 2] == 0)
			{
				num--;
				array = new byte[num];
				Array.Copy(pbData, i + 3, array, 0, (int)num);
			}
			else
			{
				array = new byte[num];
				Array.Copy(pbData, i + 2, array, 0, (int)num);
			}
			if (bReturnSecureString)
			{
				SecureString secureString = new SecureString();
				for (i = 0; i < array.Length; i++)
				{
					secureString.AppendChar(Convert.ToChar(array[i]));
				}
				return secureString;
			}
			string text = "";
			for (i = 0; i < array.Length; i++)
			{
				text += Convert.ToChar(array[i]);
			}
			return text;
		}

		public static byte[] ASNDecodeInteger(byte[] pbData)
		{
			byte[] array = null;
			uint num = 0u;
			if (pbData[0] != 2)
			{
				return null;
			}
			int i;
			if ((pbData[1] & 0x80) > 0)
			{
				uint num2 = pbData[1] & 0x7Fu;
				if (num2 > 4)
				{
					return null;
				}
				for (i = 0; i < num2; i++)
				{
					num |= (uint)(pbData[i + 2] << ((int)(num2 - 1) - i) * 8);
				}
			}
			else
			{
				num = pbData[1];
				i = 0;
			}
			if (pbData[i + 2] == 0)
			{
				num--;
				array = new byte[num];
				Array.Copy(pbData, i + 3, array, 0, (int)num);
			}
			else
			{
				array = new byte[num];
				Array.Copy(pbData, i + 2, array, 0, (int)num);
			}
			return array;
		}

		public static int CalculateInteger(byte[] pbData)
		{
			int num = 0;
			for (int i = 0; i < pbData.Length; i++)
			{
				num <<= 8;
				num |= pbData[i];
			}
			return num;
		}
	}
}
